package com.goods.crawler.service;

import com.goods.crawler.entity.Proxyip;
import com.goods.crawler.repository.ProxyIpRepository;
import com.goods.crawler.utils.WebDriverFactory;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.firefox.FirefoxProfile;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.sql.Date;
import java.util.ArrayList;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.Queue;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ConcurrentLinkedQueue;

/**
 * <pre>类名: IpTransferService</pre>
 * <pre>描述: 动态ip服务类</pre>
 * <pre>版权: 浙江理工大学信息学院</pre>
 * <pre>日期: 2019/2/17 16:50</pre>
 * <pre>作者: chenwb</pre>
 */
@Service
public class IpTransferService {

	private static Logger logger = LoggerFactory.getLogger(IpTransferService.class);


	@Value("${diff.broswer.path}")
	public String BROWSER_PATH;

	@Value("${diff.broswer.driver.path}")
	public String BROWSER_DRIVER_PATH;

	@Autowired
	private ProxyIpRepository proxyIpRepository;

	private Queue<Proxyip> proxyIps = new ArrayBlockingQueue<Proxyip>(100);

	/**
	 * @return WebDriver
	 * @Description: get webdriver with new dynamic ip
	 * @author chenwb
	 * @date 2019/2/17 16:51
	 */
	public WebDriver getNewInstance() {
		WebDriver driver = null;
		System.setProperty("webdriver.firefox.bin", BROWSER_PATH);
		FirefoxOptions options = new FirefoxOptions();
		options.setBinary(BROWSER_PATH);    //导入firefox安装路径

		FirefoxProfile firefoxProfile = new FirefoxProfile();
		this.checkProxyIp();
		Proxyip proxyip = proxyIps.poll();
		boolean isPing;
		do{
			 isPing = this.isPing(proxyip.getIpAddress());
			if(isPing){
				proxyIps.offer(proxyip);
			}else{
				proxyip = proxyIps.poll();
			}
		}while(!isPing);
		// 调用profile对象的setPreference方法，设定浏览器启动时首页显示为sogou
		/*firefoxProfile.setPreference("permissions.default.image", 2);*/
		options.setProfile(firefoxProfile);
		//options.setHeadless(true);
		firefoxProfile.setPreference("network.proxy.type", 1);
		firefoxProfile.setPreference("network.proxy.http", proxyip.getIpAddress());
		firefoxProfile.setPreference("network.proxy.http_port", proxyip.getIpPort());
		System.setProperty("webdriver.gecko.driver", BROWSER_DRIVER_PATH);
		driver = new FirefoxDriver(options);

		return driver;
	}

	/**
	 * @return void
	 * @Description: saveAllDynamicIp
	 * @author chenwb
	 * @date 2019/2/17 16:52
	 */
	@Transactional
	public void saveAllDynamicIp(List<Proxyip> proxyips) {
		List<Proxyip> proxyipList = proxyIpRepository.findAll();
		proxyIpRepository.saveAll(proxyips);
		this.deleteAllDynamicIp(proxyipList);
	}

	/**
	 * @return void
	 * @Description: deleteAllDynamicIp
	 * @author chenwb
	 * @date 2019/2/17 16:52
	 */
	@Transactional
	public void deleteAllDynamicIp(List<Proxyip> proxyips) {
		proxyIpRepository.deleteAll(proxyips);

	}

	/**
	 * @param ip
	 * @return boolean
	 * @Description: 校验ip是否有效
	 * @author chenwb
	 * @date 2019/2/17 19:51
	 */
	private boolean isPing(String ip) {
		boolean status = false;
		if (ip != null) {
			try {
				status = InetAddress.getByName(ip).isReachable(3000);
			} catch (UnknownHostException e) {

			} catch (IOException e) {

			}
		}
		return status;
	}

	/**
	 * @Description: private void checkProxyIp(){
	 * @author chenwb
	 * @date 2019/2/17 20:31
	 * @param
	 * @return 输出参数
	 */
	private void checkProxyIp(){
		try{
			proxyIps.element();
		}catch(Exception e){
			List<Proxyip> proxyIps = proxyIpRepository.findAll();
			this.createProxyIps(proxyIps);
		}
	}

	/**
	 * @Description: createProxyIps 创建代理ip队列
	 * @author chenwb
	 * @date 2019/2/17 20:32
	 * @param proxyips
	 * @return void
	 */
	private void createProxyIps(List<Proxyip> proxyips){
		for (Proxyip proxyip : proxyips) {
			if (this.isPing(proxyip.getIpAddress())) {
				logger.info("----------ip:{}有效---------", proxyip.getIpAddress());
				proxyIps.offer(proxyip);
			} else {
				logger.info("----------ip:{}无效---------", proxyip.getIpAddress());
				proxyIpRepository.delete(proxyip);
			}
		}
	}
}
